// zq_dma.h
// 修复后的代码

#ifndef ZQ_DMA_H
#define ZQ_DMA_H

#include <zq_conf.h>
#include "zq_cpu.h"

namespace zq
{
    namespace dma
    {
        namespace detail
        {
            namespace info
            {
                // DMA通道偏移量定义
                DECLARE_ATTRIBUTE(DMA,
                                  _0 = 0x0000, // DMA通道0寄存器组基地址偏移
                                  _1 = 0x0020, // DMA通道1寄存器组基地址偏移
                                  _2 = 0x0040, // DMA通道2寄存器组基地址偏移
                                  _3 = 0x0060, // DMA通道3寄存器组基地址偏移
                                  _4 = 0x0080, // DMA通道4寄存器组基地址偏移
                                  _5 = 0x00A0  // DMA通道5寄存器组基地址偏移
                )

                // DMA同步事件定义
                DECLARE_ATTRIBUTE(Event,
                                  None = 0x00,               // 00000b: 无同步事件
                                  McBSP0_Receive = 0x01,     // 00001b: McBSP0接收事件(REVTO)
                                  McBSP0_Transmit = 0x02,    // 00010b: McBSP0传输事件(XEVT0)
                                  McBSP1_Receive = 0x05,     // 00101b: McBSP1/MMC-SD1接收事件
                                  McBSP1_Transmit = 0x06,    // 00110b: McBSP1/MMC-SD1传输事件
                                  McBSP2_Receive = 0x09,     // 01001b: McBSP2/MMC-SD2接收事件
                                  McBSP2_Transmit = 0x0A,    // 01010b: McBSP2/MMC-SD2传输事件
                                  Timer0_Int = 0x0D,         // 01101b: Timer0中断事件
                                  Timer1_Int = 0x0E,         // 01110b: Timer1中断事件
                                  EXT_INT0 = 0x0F,           // 01111b: 外部中断0
                                  EXT_INT1 = 0x10,           // 10000b: 外部中断1
                                  EXT_INT2 = 0x11,           // 10001b: 外部中断2
                                  EXT_INT3 = 0x12,           // 10010b: 外部中断3
                                  EXT_INT4_or_I2C_Rec = 0x13,// 10011b: 外部中断4/或I2C接收事件
                                  I2C_Transmit = 0x14,       // 10100b: I2C传输事件(XEVT12C)
                                  _RSVD_00011b = 0x03,       // 00011b: 保留
                                  _RSVD_00100b = 0x04,       // 00100b: 保留
                                  _RSVD_00111b = 0x07,       // 00111b: 保留
                                  _RSVD_01000b = 0x08,       // 01000b: 保留
                                  _RSVD_01011b = 0x0B,       // 01011b: 保留
                                  _RSVD_01100b = 0x0C,       // 01100b: 保留
                                  _RSVD_Other = 0x15         // 10101b及以上: 保留
                )
            }

            namespace regs
            {
                // ============== 全局寄存器 (所有通道共用) ==============
                DECLARE_MMR_REGISTER(GCR, 0x0E00)  // DMA全局控制寄存器
                DECLARE_MMR_REGISTER(GSCR, 0x0E02) // DMA软件兼容性寄存器
                DECLARE_MMR_REGISTER(GTCR, 0x0E03) // DMA超时控制寄存器

                // ============== 通道级寄存器模板 ==============
                template<info::DMA::Type dma>
                struct DMAChannel
                {
                    // 源/目标参数寄存器 (DMACSDP)
                    BEGIN_MMR_REGISTER(CSDP, 0x0C00 + dma)

                        // [15:14] 目的突发使能 (DSTBEN)
                        // 00b: 禁止突发  10b: 使能突发  其他: 保留
                        DECLARE_MMR_BITS_FIELD(DSTBEN, 2, 14)

                        // [13] 目的打包使能 (DSTPACK)
                        // 0: 不打包  1: 打包
                        DECLARE_MMR_BIT(DSTPACK, 13)

                        // [12:9] 目的端口选择 (DST)
                        // 0000b: SARAM  0001b: DARAM
                        // 0010b: 外部内存  0011b: 外设
                        DECLARE_MMR_BITS_FIELD(DST, 4, 9)

                        // [8:7] 源突发使能 (SRCBEN)
                        // 00b: 禁止突发  10b: 使能突发  其他: 保留
                        DECLARE_MMR_BITS_FIELD(SRCBEN, 2, 7)

                        // [6] 源打包使能 (SRCPACK)
                        // 0: 不打包  1: 打包
                        DECLARE_MMR_BIT(SRCPACK, 6)

                        // [5:2] 源端口选择 (SRC)
                        // 0000b: SARAM  0001b: DARAM
                        // 0010b: 外部内存  0011b: 外设
                        DECLARE_MMR_BITS_FIELD(SRC, 4, 2)

                        // [1:0] 数据尺寸 (DATATYPE)
                        // 00b: 8位  01b: 16位  10b: 32位  11b: 保留
                        DECLARE_MMR_BITS_FIELD(DataSize, 2, 0)

                    END_MMR_REGISTER()

                    // DMA通道控制寄存器(DMACCR)
                    BEGIN_MMR_REGISTER(CCR, 0x0C01 + dma)

                        // [15:14] 目标地址模式 (DSTAMODE)
                        // 00b: 常量地址 (传输期间地址不变)
                        // 01b: 后递增 (根据数据类型自动增加地址)
                        // 10b: 单索引 (传输后地址增加元素索引值) 每次元素传输后地址 += 元素索引
                        // 11b: 双索引 (帧内用元素索引，帧间用帧索引)    帧内元素索引/帧间帧索引
                        DECLARE_MMR_BITS_FIELD(DST_AMODE, 2, 14)

                        // [13:12] 源地址模式 (SRCAMODE)
                        // 00b: 常量地址 (传输期间地址不变)
                        // 01b: 后递增 (根据数据类型自动增加地址)
                        // 10b: 单索引 (传输后地址增加元素索引值)
                        // 11b: 双索引 (帧内用元素索引，帧间用帧索引)
                        DECLARE_MMR_BITS_FIELD(SRC_AMODE, 2, 12)

                        // [11] 结束编程标志 (ENDPROG)
                        // 0: 配置寄存器可编程/编程中
                        // 1: 编程结束 (表示CPU已完成配置)
                        DECLARE_MMR_BIT(END_PROG, 11)

                        // [10] 保留位 (必须写0)
                        DECLARE_MMR_BIT(Reserved1, 10)

                        // [9] 重复模式 (REPEAT)
                        // 0: 仅在ENDPROG=1时重复 (需CPU握手)
                        // 1: 无条件重复 (忽略ENDPROG状态)
                        DECLARE_MMR_BIT(REPEAT, 9)

                        // [8] 自动初始化 (AUTOINIT)
                        // 0: 禁用自动初始化
                        // 1: 使能自动初始化 (块传输完成后自动重载)
                        DECLARE_MMR_BIT(AUTO_INIT, 8)

                        // [7] 通道使能 (EN)
                        // 0: 禁用通道  1: 启用通道
                        DECLARE_MMR_BIT(EN, 7)

                        // [6] 通道优先级 (PRIO)
                        // 0: 低优先级  1: 高优先级
                        DECLARE_MMR_BIT(PRIO, 6)

                        // [5] 帧同步模式 (FS)
                        // 0: 元素同步 (每个元素需事件触发)
                        // 1: 帧同步 (每帧只需一个事件触发)
                        DECLARE_MMR_BIT(FS, 5)

                        // [4:0] 同步事件选择 (SYNC)
                        // 00000b: 无同步事件 (立即启动)
                        // 其他值: 选择特定外设事件作为同步源
                        DECLARE_MMR_BITS_FIELD(SYNC, 5, 0)

                    END_MMR_REGISTER()

                    // 中断控制寄存器 (DMACICR)
                    BEGIN_MMR_REGISTER(CICR, 0x0C02 + dma)

                        // [5] 块传输完成中断使能 (BLOCKIE)
                        // 0: 禁用  1: 使能
                        DECLARE_MMR_BIT(BLOCKIE, 5)

                        // [4] 最后传输中断使能 (LASTIE)
                        // 0: 禁用  1: 使能
                        DECLARE_MMR_BIT(LASTIE, 4)

                        // [3] 帧传输完成中断使能 (FRAMEIE)
                        // 0: 禁用  1: 使能
                        DECLARE_MMR_BIT(FRAMEIE, 3)

                        // [2] 半帧传输中断使能 (HALFIE)
                        // 0: 禁用  1: 使能
                        DECLARE_MMR_BIT(HALFIE, 2)

                        // [1] 事件丢失中断使能 (DROPIE)
                        // 0: 禁用  1: 使能
                        DECLARE_MMR_BIT(DROPIE, 1)

                        // [0] 超时中断使能 (TIMEOUTIE)
                        // 0: 禁用  1: 使能
                        DECLARE_MMR_BIT(TIMEOUTIE, 0)

                    END_MMR_REGISTER()

                    // 状态寄存器 (DMACSR, 只读)
                    BEGIN_MMR_REGISTER(CSR, 0x0C03 + dma)

                        // [6] 块传输中断挂起 (BLOCKIP)
                        // 0: 无中断  1: 块传输完成中断发生
                        DECLARE_MMR_BIT(BLOCKIP, 6)

                        // [5] 最后传输中断挂起 (LASTIP)
                        // 0: 无中断  1: 最后帧传输开始中断发生
                        DECLARE_MMR_BIT(LASTIP, 5)

                        // [4] 帧传输中断挂起 (FRAMEIP)
                        // 0: 无中断  1: 帧传输完成中断发生
                        DECLARE_MMR_BIT(FRAMEIP, 4)

                        // [3] 半帧传输中断挂起 (HALFIP)
                        // 0: 无中断  1: 半帧传输完成中断发生
                        DECLARE_MMR_BIT(HALFIP, 3)

                        // [2] 事件丢失中断挂起 (DROPIP)
                        // 0: 无事件丢失  1: 事件丢失发生
                        DECLARE_MMR_BIT(DROPIP, 2)

                        // [1] 超时中断挂起 (TIMEOUTIP)
                        // 0: 未超时  1: 超时发生
                        DECLARE_MMR_BIT(TIMEOUTIP, 1)

                        // [0] 通道激活状态 (ACTIVE)
                        // 0: 空闲  1: 传输中
                        DECLARE_MMR_BIT(ACTIVE, 0)

                    END_MMR_REGISTER()

                    // 源起始地址寄存器 (32位)
                    DECLARE_MMR_REGISTER(CSSA_L, 0x0C04 + dma) // [15:0]
                    DECLARE_MMR_REGISTER(CSSA_U, 0x0C05 + dma) // [31:16]

                    // 目标起始地址寄存器 (32位)
                    DECLARE_MMR_REGISTER(CDSA_L, 0x0C06 + dma) // [15:0]
                    DECLARE_MMR_REGISTER(CDSA_U, 0x0C07 + dma) // [31:16]

                    // 传输计数寄存器
                    DECLARE_MMR_REGISTER(CEN, 0x0C08 + dma) // 元素数量/帧
                    DECLARE_MMR_REGISTER(CFN, 0x0C09 + dma) // 帧数量/块

                    // 索引寄存器
                    DECLARE_MMR_REGISTER(CFI, 0x0C0A + dma) // 源帧索引
                    DECLARE_MMR_REGISTER(CEI, 0x0C0B + dma) // 源元素索引

                    // 地址计数器 (只读)
                    DECLARE_MMR_REGISTER(CSAC, 0x0C0C + dma) // 当前源地址
                    DECLARE_MMR_REGISTER(CDAC, 0x0C0D + dma) // 当前目标地址

                    // 目标索引寄存器 (仅5509A有效)
                    DECLARE_MMR_REGISTER(CDEI, 0x0C0E + dma) // 目标元素索引
                    DECLARE_MMR_REGISTER(CDFI, 0x0C0F + dma) // 目标帧索引
                };
            }
        }

        /**
         *  DMA控制类
         * @tparam dma DMA通道编号
         * @code 使用示例
             // 配置DMA0用于McBSP0接收
            DMA0::Config cfg;
            cfg.srcAddrMode = 0;       // 源地址模式：常量地址（McBSP寄存器固定）
            cfg.dstAddrMode = 1;       // 目标地址模式：后递增（存入数组）
            cfg.dataSize = 1;          // 16位数据
            cfg.autoinit = true;       // 自动重新加载
            // 这两个端口不能设置错误，否则DMA无法正常启动
            cfg.srcPort = 3;           // 源端口：外设（McBSP）
            cfg.dstPort = 1;           // 目标端口：0:SARAM（内存） 1:DARAM

            DMA0::init(cfg);
            DMA0::enableIT(true);

            // 启动DMA传输
            DMA0::start(
                dma::detail::info::Event::McBSP0_Receive,   // 同步事件
                mcbsp::regs::drr1::REG,                     // McBSP接收寄存器字节地址
                reinterpret_cast<uint32_t>(buf_adc),        // 缓冲区字节地址
                FFT_SIZE                                    // 元素数量
            );
         */
        template<detail::info::DMA::Type dma>
        class Control
        {
            typedef typename detail::regs::DMAChannel<dma>::CCR CCR_REG;
            typedef typename detail::regs::DMAChannel<dma>::CSDP CSDP_REG;
            typedef typename detail::regs::DMAChannel<dma>::CICR CICR_REG;
            typedef typename detail::regs::DMAChannel<dma>::CSR CSR_REG;
            typedef typename detail::regs::DMAChannel<dma>::CSSA_L CSSA_L_REG;
            typedef typename detail::regs::DMAChannel<dma>::CSSA_U CSSA_U_REG;
            typedef typename detail::regs::DMAChannel<dma>::CDSA_L CDSA_L_REG;
            typedef typename detail::regs::DMAChannel<dma>::CDSA_U CDSA_U_REG;
            typedef typename detail::regs::DMAChannel<dma>::CEN CEN_REG;
            typedef typename detail::regs::DMAChannel<dma>::CFN CFN_REG;
            typedef typename detail::regs::DMAChannel<dma>::CEI CEI_REG;
            typedef typename detail::regs::DMAChannel<dma>::CFI CFI_REG;
            typedef typename detail::regs::DMAChannel<dma>::CDEI CDEI_REG;
            typedef typename detail::regs::DMAChannel<dma>::CDFI CDFI_REG;

        public:
            // 中断标志
            struct IT_Flags
            {
                enum Type
                {
                    blockIE = 1 << 6, // 块传输完成中断
                    lastIE = 1 << 5, // 最后传输中断
                    frameIE = 1 << 4, // 帧传输完成中断
                    halfIE = 1 << 3, // 半帧传输中断
                    dropIE = 1 << 2, // 事件丢失中断
                    timeoutIE = 1 << 1, // 超时中断
                    active = 1 << 0 // 通道激活状态
                };
            };

            // DMA配置结构体
            struct Config
            {
                // --- CSDP寄存器配置 ---
                unsigned int dstBen; // [15:14] 目的突发使能
                unsigned int dstPack; // [13] 目的打包使能
                unsigned int dstPort; // [12:9] 目的端口选择 这个端口不能设置错误，否则DMA无法正常启动
                unsigned int srcBen; // [8:7] 源突发使能
                unsigned int srcPack; // [6] 源打包使能
                unsigned int srcPort; // [5:2] 源端口选择 这个端口不能设置错误，否则DMA无法正常启动
                unsigned int dataSize; // [1:0] 数据尺寸

                // --- CCR寄存器配置 ---
                unsigned int dstAddrMode; // [15:14] 目标地址模式
                unsigned int srcAddrMode; // [13:12] 源地址模式
                bool fs; // [5] 帧同步模式
                bool priority; // [6] 通道优先级
                bool autoinit; // [8] 自动初始化
                bool mode; // [9] 重复传输模式

                // 索引配置（二维数据传输）
                short srcElementIndex; // 源元素索引
                short srcFrameIndex; // 源帧索引
                short dstElementIndex; // 目标元素索引
                short dstFrameIndex; // 目标帧索引

                // 构造函数设置默认值
                Config() : dstBen(0), dstPack(0), dstPort(0),
                           srcBen(0), srcPack(0), srcPort(0),
                           dataSize(1), // 默认16位数据
                           dstAddrMode(0), srcAddrMode(0),
                           fs(false), priority(false), autoinit(false), mode(false),
                           srcElementIndex(0), srcFrameIndex(0),
                           dstElementIndex(0), dstFrameIndex(0)
                {
                }
            };

            // 使用自定义配置初始化
            static void init(const Config &config)
            {
                // 禁用通道
                CCR_REG::EN::clear();

                // 配置CSDP寄存器
                CSDP_REG::DSTBEN::write_bits(config.dstBen);
                CSDP_REG::DSTPACK::write_bit(config.dstPack);
                CSDP_REG::DST::write_bits(config.dstPort);
                CSDP_REG::SRCBEN::write_bits(config.srcBen);
                CSDP_REG::SRCPACK::write_bit(config.srcPack);
                CSDP_REG::SRC::write_bits(config.srcPort);
                CSDP_REG::DataSize::write_bits(config.dataSize);

                // 配置索引寄存器
                CEI_REG::write(config.srcElementIndex);
                CFI_REG::write(config.srcFrameIndex);
                CDEI_REG::write(config.dstElementIndex);
                CDFI_REG::write(config.dstFrameIndex);

                // 配置CCR寄存器
                CCR_REG::DST_AMODE::write_bits(config.dstAddrMode);
                CCR_REG::SRC_AMODE::write_bits(config.srcAddrMode);
                CCR_REG::FS::write_bit(config.fs);  // 默认关闭帧同步，即使用元素同步，确保每个元素都按照时序传输
                CCR_REG::PRIO::write_bit(config.priority);
                CCR_REG::AUTO_INIT::write_bit(config.autoinit);
                CCR_REG::REPEAT::write_bit(config.mode);

                // 清除停止标志
                CCR_REG::END_PROG::clear();

                // 默认启用CPU中断（DMA的中断没开，所以实际上中断并不会触发）
                if (dma==detail::info::DMA::_0)
                {
                    cpu::IER1::DMAC0::set();
                    cpu::DBIER1::DMAC0::set();
                }

                if (dma==detail::info::DMA::_1)
                {
                    cpu::IER0::DMAC1::set();
                    cpu::DBIER0::DMAC1::set();
                }

                if (dma==detail::info::DMA::_2)
                {
                    cpu::IER1::DMAC2::set();
                    cpu::DBIER1::DMAC2::set();
                }

                if (dma==detail::info::DMA::_3)
                {
                    cpu::IER1::DMAC3::set();
                    cpu::DBIER1::DMAC3::set();
                }

                if (dma==detail::info::DMA::_4)
                {
                    cpu::IER0::DMAC4::set();
                    cpu::DBIER0::DMAC4::set();
                }

                if (dma==detail::info::DMA::_5)
                {
                    cpu::IER0::DMAC5::set();
                    cpu::DBIER0::DMAC5::set();
                }
            }


            // 启动DMA传输(多帧)
            static void start(
                detail::info::Event::Type event, // 同步事件
                uint32_t srcAddr, // 源地址(32位)
                uint32_t dstAddr, // 目标地址(32位) I/O地址空间和存储器地址必须都要左移一位
                uint16_t elementCount, // 每帧元素数
                uint16_t frameCount = 1// 帧数量
            )
            {
                // 禁用通道
                CCR_REG::EN::clear();

                // 配置地址寄存器
                srcAddr <<= 1; // I/O地址空间和存储器地址必须都要左移一位
                dstAddr <<= 1; // I/O地址空间和存储器地址必须都要左移一位
                CSSA_L_REG::write(srcAddr & 0xFFFF);
                CSSA_U_REG::write((srcAddr >> 16) & 0xFFFF);
                CDSA_L_REG::write(dstAddr & 0xFFFF);
                CDSA_U_REG::write((dstAddr >> 16) & 0xFFFF);

                // 配置传输数量
                CEN_REG::write(elementCount);
                CFN_REG::write(frameCount);

                // 设置同步事件
                CCR_REG::SYNC::write_bits(event);

                // 在AutoInit为1，REPEAT为0时，只要设置END_PROG=1（比如在中断里设置），就会自动开始新一轮（只有1轮）
                // 确保自动初始化握手完成
                if (CCR_REG::AUTO_INIT::read_bit()) {
                    CCR_REG::END_PROG::set();
                }

                // 使能通道
                CCR_REG::EN::set();
            }

            // 停止DMA传输
            static void stop()
            {
                // 设置停止标志
                CCR_REG::END_PROG::set();
                // 禁用通道
                CCR_REG::EN::clear();
            }


            // 检查通道激活状态
            static bool isActive()
            {
                return CSR_REG::ACTIVE::read_bit();
            }

            // 配置中断
            static void enableIT(
                bool blockIE = false, // 块传输完成中断
                bool lastIE = false, // 最后传输中断
                bool frameIE = false, // 帧传输完成中断
                bool halfIE = false, // 半帧传输中断
                bool dropIE = false, // 事件丢失中断
                bool timeoutIE = false // 超时中断
            )
            {
                CICR_REG::BLOCKIE::write_bit(blockIE);
                CICR_REG::LASTIE::write_bit(lastIE);
                CICR_REG::FRAMEIE::write_bit(frameIE);
                CICR_REG::HALFIE::write_bit(halfIE);
                CICR_REG::DROPIE::write_bit(dropIE);
                CICR_REG::TIMEOUTIE::write_bit(timeoutIE);
            }

            // 清除中断标志
            static void clearInterruptFlags()
            {
                // 读取状态寄存器会自动清除标志位
                const volatile uint16_t status = CSR_REG::read();
                it_flags = status; // 对齐标志位
            }

            static bool getITFlags(const uint16_t flags)
            {
                const uint16_t ret = it_flags & flags;
                it_flags &= ~flags; // 清除指定的标志
                return ret ? true : false;
            }

            /**
             * @brief 重新进行传输，当且仅当autoinit设置为1的情况下
             */
            static void restart()
            {
                CCR_REG::END_PROG::set();
            }


            // 检查传输是否完成
            static bool isTransferComplete()
            {
                // 检查关键标志位：
                // 1. ACTIVE位(bit0) - 为0表示通道空闲
                // 2. BLOCKIP位(bit6) - 为1表示块传输完成
                // 3. 元素计数器(CEN) - 为0表示所有元素已传输
                return CSR_REG::ACTIVE::read_bit_not() && CSR_REG::BLOCKIP::read_bit()
                       && CEN_REG::read() == 0;
            }

            // ====================== 另一套接口 ======================
        public:
            struct config
            {
                // 基础初始化，必须在config里的其他函数前使用(其实可以使用RAII 模式，但是感觉与其他函数调用形式不协调，有些丑）
                static void baseInit()
                {
                    const Config cfg;
                    init(cfg);
                }

                // ================= 地址模式配置 =================
                struct srcAddrMode
                {
                    // 源地址模式：常量地址（传输期间地址不变）
                    static void constant()
                    {
                        CCR_REG::SRC_AMODE::write_bits(0); // 00b: 常量地址模式
                    }

                    // 源地址模式：后递增（根据数据类型自动增加地址）
                    static void increase()
                    {
                        CCR_REG::SRC_AMODE::write_bits(1); // 01b: 自动后递增模式
                    }

                    // 源地址模式：单索引（传输后地址增加元素索引值）
                    static void singleIndex()
                    {
                        CCR_REG::SRC_AMODE::write_bits(2); // 10b: 单索引模式
                    }

                    // 源地址模式：双索引（帧内用元素索引，帧间用帧索引）
                    static void dualIndex()
                    {
                        CCR_REG::SRC_AMODE::write_bits(3); // 11b: 双索引模式
                    }
                };
                // 循环模式
                struct circleLoop
                {
                    static void enable(){CCR_REG::AUTO_INIT::set();CCR_REG::REPEAT::set();}
                    static void disable(){CCR_REG::AUTO_INIT::clear();CCR_REG::REPEAT::clear();}
                };

                struct dstAddrMode
                {
                    // 目标地址模式：常量地址（传输期间地址不变）
                    static void constant()
                    {
                        CCR_REG::DST_AMODE::write_bits(0); // 00b: 常量地址模式
                    }

                    // 目标地址模式：后递增（根据数据类型自动增加地址）
                    static void increase()
                    {
                        CCR_REG::DST_AMODE::write_bits(1); // 01b: 自动后递增模式
                    }

                    // 目标地址模式：单索引（传输后地址增加元素索引值）
                    static void singleIndex()
                    {
                        CCR_REG::DST_AMODE::write_bits(2); // 10b: 单索引模式
                    }

                    // 目标地址模式：双索引（帧内用元素索引，帧间用帧索引）
                    static void dualIndex()
                    {
                        CCR_REG::DST_AMODE::write_bits(3); // 11b: 双索引模式
                    }
                };

                // ================= 数据尺寸配置 =================
                struct dataSize
                {
                    // 设置数据尺寸为8位
                    static void _8bit()
                    {
                        CSDP_REG::DataSize::write_bits(0); // 00b: 8位数据
                    }

                    // 设置数据尺寸为16位
                    static void _16bit()
                    {
                        CSDP_REG::DataSize::write_bits(1); // 01b: 16位数据
                    }

                    // 设置数据尺寸为32位
                    static void _32bit()
                    {
                        CSDP_REG::DataSize::write_bits(2); // 10b: 32位数据
                    }
                };

                // ================= 自动初始化配置 =================
                struct autoinit
                {
                    // 启用自动初始化（块传输完成后自动重载上下文）
                    static void enable()
                    {
                        CCR_REG::AUTO_INIT::set(); // 1: 使能自动初始化
                    }

                    // 禁用自动初始化
                    static void disable()
                    {
                        CCR_REG::AUTO_INIT::clear(); // 0: 禁用自动初始化
                    }
                };

                // ================= 端口配置 =================
                struct srcPort
                {
                    // 源端口：SARAM（内部单访问RAM）
                    static void saram()
                    {
                        CSDP_REG::SRC::write_bits(0); // 0000b: SARAM
                    }

                    // 源端口：DARAM（内部双访问RAM）
                    static void dram()
                    {
                        CSDP_REG::SRC::write_bits(1); // 0001b: DARAM
                    }

                    // 源端口：外部内存（通过EMIF访问）
                    static void external()
                    {
                        CSDP_REG::SRC::write_bits(2); // 0010b: 外部内存
                    }

                    // 源端口：外设（通过外设总线控制器访问）
                    static void peripheral()
                    {
                        CSDP_REG::SRC::write_bits(3); // 0011b: 外设
                    }
                };

                struct dstPort
                {
                    // 目标端口：SARAM（内部单访问RAM）
                    static void saram()
                    {
                        CSDP_REG::DST::write_bits(0); // 0000b: SARAM
                    }

                    // 目标端口：DARAM（内部双访问RAM）
                    static void dram()
                    {
                        CSDP_REG::DST::write_bits(1); // 0001b: DARAM
                    }

                    // 目标端口：外部内存（通过EMIF访问）
                    static void external()
                    {
                        CSDP_REG::DST::write_bits(2); // 0010b: 外部内存
                    }

                    // 目标端口：外设（通过外设总线控制器访问）
                    static void peripheral()
                    {
                        CSDP_REG::DST::write_bits(3); // 0011b: 外设
                    }
                };

                // ================= 帧同步配置 =================
                struct frameSync
                {
                    // 启用帧同步（每帧只需一个事件触发）
                    static void enable()
                    {
                        CCR_REG::FS::set(); // 1: 帧同步模式
                    }

                    // 禁用帧同步（每个元素需事件触发）
                    static void disable()
                    {
                        CCR_REG::FS::clear(); // 0: 元素同步模式
                    }
                };

                // ================= 优先级配置 =================
                struct priority
                {
                    // 设置通道为高优先级
                    static void high()
                    {
                        CCR_REG::PRIO::set(); // 1: 高优先级
                    }

                    // 设置通道为低优先级
                    static void low()
                    {
                        CCR_REG::PRIO::clear(); // 0: 低优先级
                    }
                };

                // ================= 索引配置 =================
                // 仅在地址索引模式配置为单/双索引模式生效
                struct srcIndex
                {
                    static void set(short element, short frame = 0)
                    {
                        CEI_REG::write(element);
                        CFI_REG::write(frame);
                    }
                };

                struct dstIndex
                {
                    static void set(short element, short frame = 0)
                    {
                        CDEI_REG::write(element);
                        CDFI_REG::write(frame);
                    }
                };

                // ================= 预设模式配置 =================
                struct mode
                {
                    // 外设到内存的传输预设(内存指的是DARAM)
                    // 默认使用块传输中断，自动初始化使能
                    static void peripheralToMemory(const bool it_block = true)
                    {
                        baseInit();
                        srcAddrMode::constant();   // 源(外设)常量地址
                        dstAddrMode::increase();   // 目标(内存)自增
                        srcPort::peripheral();     // 源端口：外设
                        dstPort::dram();           // 目标端口：DARAM
                        dataSize::_16bit();        // 16位数据
                        autoinit::enable();        // 自动初始化使能

                        if (it_block)
                            itConfig::block::enable();// 默认使用块传输中断
                    }

                    // 内存到外设的传输预设(内存指的是SARAM)
                    // 默认使用块传输中断，自动初始化使能
                    static void memoryToPeripheral(const bool it_block = true)
                    {
                        baseInit();
                        srcAddrMode::increase();   // 源(内存)自增
                        dstAddrMode::constant();   // 目标(外设)常量地址
                        srcPort::saram();           // 源端口：SARAM
                        dstPort::peripheral();     // 目标端口：外设
                        dataSize::_16bit();        // 16位数据
                        autoinit::enable();        // 自动初始化使能

                        if (it_block)
                            itConfig::block::enable();// 默认使用块传输中断
                    }
                };

                // ================= 中断配置 =================
                struct itConfig
                {
                    // 块传输完成中断
                    struct block
                    {
                        static void enable() { CICR_REG::BLOCKIE::set(); }

                        static void disable() { CICR_REG::BLOCKIE::clear(); }
                    };

                    // 最后传输中断
                    struct last
                    {
                        static void enable() { CICR_REG::LASTIE::set(); }

                        static void disable() { CICR_REG::LASTIE::clear(); }
                    };

                    // 帧传输完成中断
                    struct frame
                    {
                        static void enable() { CICR_REG::FRAMEIE::set(); }

                        static void disable() { CICR_REG::FRAMEIE::clear(); }
                    };

                    // 半帧传输中断
                    struct half
                    {
                        static void enable() { CICR_REG::HALFIE::set(); }

                        static void disable() { CICR_REG::HALFIE::clear(); }
                    };

                    // 事件丢失中断
                    struct drop
                    {
                        static void enable() { CICR_REG::DROPIE::set(); }

                        static void disable() { CICR_REG::DROPIE::clear(); }
                    };

                    // 超时中断
                    struct timeout
                    {
                        static void enable() { CICR_REG::TIMEOUTIE::set(); }

                        static void disable() { CICR_REG::TIMEOUTIE::clear(); }
                    };
                };
            };

        private:
            static uint16_t it_flags;
        };
    }

    // 显式实例化
    typedef dma::Control<dma::detail::info::DMA::_0> DMA0;
    typedef dma::Control<dma::detail::info::DMA::_1> DMA1;
    typedef dma::Control<dma::detail::info::DMA::_2> DMA2;
    typedef dma::Control<dma::detail::info::DMA::_3> DMA3;
    typedef dma::Control<dma::detail::info::DMA::_4> DMA4;
    typedef dma::Control<dma::detail::info::DMA::_5> DMA5;
}

#endif // ZQ_DMA_H
